package com.an.demo.controller;

import java.io.*;
import java.util.*;

public class PythonExecutor {

    public static void main(String[] args) {
        // 设置工作目录和文件路径
        // 要进入的文件目录
        String workingDirectory = "D:\\Desktop\\reclassify_and_stat";
        // Python 脚本的相对路径（在工作目录下）
        String pythonScriptPath = "nvdi_reclassify.py";
        // 配置文件路径
        String configFilePath = "config.json";
        
        // 安装所需的 Python 库
        String[] requiredLibraries = {
            "numpy",
            "pandas",
            "rasterio",
            "geopandas",
            "rasterstats"
        };

        try {
            // 1. 进入目标文件目录，创建虚拟环境并激活
            createAndActivateVirtualEnv(workingDirectory);

            // 2. 安装 Python 依赖
            installDependencies(workingDirectory, requiredLibraries);
            
            // 3. 执行 Python 脚本并传入配置文件
            executePythonScript(workingDirectory, pythonScriptPath, configFilePath);

        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建并激活虚拟环境
     *
     * @param workingDirectory 工作目录
     * @throws IOException          io异常
     * @throws InterruptedException 中断异常
     * @author ANH
     * @date 2024/12/18
     */
    private static void createAndActivateVirtualEnv(String workingDirectory) throws IOException, InterruptedException {
        // 创建虚拟环境，"venv" 为虚拟环境目录名
        String createEnvCommand = "python -m venv venv";

        // 使用 ProcessBuilder 执行命令
        ProcessBuilder createEnvProcessBuilder = new ProcessBuilder();
        // Windows 下使用 cmd 执行
        createEnvProcessBuilder.command("cmd", "/c", createEnvCommand);
        // 设置工作目录
        createEnvProcessBuilder.directory(new File(workingDirectory));

        // 启动进程
        Process createEnvProcess = createEnvProcessBuilder.start();
        // 打印创建虚拟环境过程的输出
        printProcessOutput(createEnvProcess);

        // 等待命令执行完成
        int createEnvExitCode = createEnvProcess.waitFor();
        System.out.println("Virtual environment created with exit code: " + createEnvExitCode);

        // 激活虚拟环境的命令
        String activateEnvCommand;
        if (System.getProperty("os.name").toLowerCase().contains("win")) {
            // Windows 下激活虚拟环境
            activateEnvCommand = "venv\\Scripts\\activate";
        } else {
            // Linux/macOS 下激活虚拟环境
            activateEnvCommand = "source venv/bin/activate";
        }

        // 执行激活命令
        ProcessBuilder activateEnvProcessBuilder = new ProcessBuilder();
        // 使用 bash 执行激活命令
        activateEnvProcessBuilder.command("cmd", "/c", activateEnvCommand);
        // 设置工作目录
        activateEnvProcessBuilder.directory(new File(workingDirectory));

        // 启动激活进程
        Process activateEnvProcess = activateEnvProcessBuilder.start();
        // 打印激活虚拟环境过程的输出
        printProcessOutput(activateEnvProcess);

        // 等待激活命令执行完成
        int activateEnvExitCode = activateEnvProcess.waitFor();
        System.out.println("Virtual environment activated with exit code: " + activateEnvExitCode);
    }


    /**
     * 安装依赖项
     *
     * @param workingDirectory  工作目录
     * @param requiredLibraries 必需库
     * @throws IOException          io异常
     * @throws InterruptedException 中断异常
     * @author ANH
     * @date 2024/12/18
     */
    private static void installDependencies(String workingDirectory, String[] requiredLibraries) throws IOException, InterruptedException {
        // 构建 pip install 命令
        String installCommand = "pip install " + String.join(" ", requiredLibraries);

        // 使用 ProcessBuilder 执行安装命令
        ProcessBuilder installProcessBuilder = new ProcessBuilder();
        // 使用 bash 执行 pip 命令
        installProcessBuilder.command("cmd", "/c", installCommand);
        // 设置工作目录
        installProcessBuilder.directory(new File(workingDirectory));

        // 启动安装进程
        Process installProcess = installProcessBuilder.start();
        // 打印安装过程的输出
        printProcessOutput(installProcess);

        // 等待安装过程完成
        int exitCode = installProcess.waitFor();
        System.out.println("Dependencies installation finished with exit code: " + exitCode);
    }


    /**
     * 执行 Python 脚本
     *
     * @param workingDirectory 工作目录
     * @param pythonScriptPath Python 脚本路径
     * @param configFilePath   配置文件路径
     * @throws IOException          io异常
     * @throws InterruptedException 中断异常
     * @author ANH
     * @date 2024/12/18
     */
    private static void executePythonScript(String workingDirectory, String pythonScriptPath, String configFilePath) throws IOException, InterruptedException {
        // 构建 Python 执行命令
        List<String> command = new ArrayList<>();
        command.add("python");
        command.add(pythonScriptPath);
        command.add("--config");
        // 配置文件作为命令行参数
        command.add(configFilePath);

        // 使用 ProcessBuilder 执行 Python 脚本
        ProcessBuilder processBuilder = new ProcessBuilder(command);
        // 设置工作目录
        processBuilder.directory(new File(workingDirectory));

        // 启动 Python 脚本执行进程
        Process process = processBuilder.start();
        // 打印脚本执行过程的输出
        printProcessOutput(process);

        // 等待进程完成
        int exitCode = process.waitFor();
        System.out.println("Python script finished with exit code: " + exitCode);
    }

    /**
     * 打印过程输出
     *
     * @param process 过程
     * @throws IOException io异常
     * @author ANH
     * @date 2024/12/18
     */
    private static void printProcessOutput(Process process) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line;
        while ((line = reader.readLine()) != null) {
            // 打印输出
            System.out.println(line);
        }
        // 打印错误输出（stderr）
        BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
        while ((line = errorReader.readLine()) != null) {
            // 打印错误输出
            System.err.println(line);
        }
    }
}
